<?php
abstract class system_session_abstract {
	protected static $_writable = false;
	protected static $_readable = false;
	protected static $_expiringData = array();
	const _THROW_NOT_WRITABLE_MSG = 'system_session is currently marked as read-only.';
	const _THROW_NOT_READABLE_MSG = 'system_session is not marked as readable.';
	
	protected static function _namespaceIsset($namespace, $name = null) {
		if(self::$_readable === false) {
			throw new system_session_exception(self::_THROW_NOT_READABLE_MSG);
		}
		if($name === null) {
			return (isset($_SESSION[$namespace]) || isset(self::$_expiringData[$namespace]));
		} else {
			return (isset($_SESSION[$namespace][$name]) || isset(self::$_expiringData[$namespace][$name]));
		}
	}
	
	protected static function _namespaceUnset($namespace, $name = null) {
		if(self::$_writable === false) {
			throw new system_session_exception(self::_THROW_NOT_WRITABLE_MSG);
		}
		$name = (string) $name;
		if($name === '') {
			unset($_SESSION[$namespace]);
			unset(self::$_expiringData[$namespace]);
		} else {
			unset($_SESSION[$namespace][$name]);
			unset(self::$_expiringData[$namespace]);
		}
		if(empty($_SESSION[$namespace])) {
			unset($_SESSION[$namespace]);
		}
	}
	
	protected static function &_namespaceGet($namespace, $name = null) {
		if(self::$_readable === false) {
			throw new system_session_exception(self::_THROW_NOT_READABLE_MSG);
		}
		if($name === null) {
			if(isset($_SESSION[$namespace])) {
				return $_SESSION[$namespace];
			} elseif(isset(self::$_expiringData[$namespace])) {
				return self::$_expiringData[$namespace];
			} else {
				return $_SESSION[$namespace];
			}
		} else {
			if(isset($_SESSION[$namespace][$name])) {
				return $_SESSION[$namespace][$name];
			} elseif(isset(self::$_expiringData[$namespace][$name])) {
				return self::$_expiringData[$namespace][$name];
			} else {
				return $_SESSION[$namespace][$name];
			}
		}
	}
	
	protected static function _namespaceGetAll($namespace) {
		$currentData = (isset($_SESSION[$namespace]) && is_array($_SESSION[$namespace])) ? $_SESSION[$namespace] : array();
		$expiringData = (isset(self::$_expiringData[$namespace]) && is_array(self::$_expiringData[$namespace])) ? self::$_expiringData[$namespace] : array();
		return array_merge($currentData, $expiringData);
	}
}
